package com.ar4j;

import javax.sql.DataSource;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;

import com.ar4j.sql.INamedQuerySource;

/**
 * The context in which active records execute their operations
 */
public class ActiveRecordContext {
  private DataSource dataSource;
  private JdbcTemplate template;
  private SimpleJdbcTemplate simpleTemplate;
  private boolean readOnly;
  private INamedQuerySource namedQuerySource;
  private PlatformTransactionManager platformTransactionManager;
  
  public DataSource getDataSource() {
    return dataSource;
  }

  public JdbcTemplate getTemplate() {
    return template;
  }

  public SimpleJdbcTemplate getSimpleTemplate() {
    return simpleTemplate;
  }
  
  public ActiveRecordContext setDataSource(DataSource dataSource) {
    this.dataSource = dataSource;
    this.template = new JdbcTemplate(dataSource);
    this.simpleTemplate = new SimpleJdbcTemplate(template);
    
    return this;
  }
  
  public boolean isReadOnly() {
    return readOnly;
  }

  public ActiveRecordContext setReadOnly(boolean readOnly) {
    this.readOnly = readOnly;
    return this;
  }
  
  public INamedQuerySource getNamedQuerySource() {
    return namedQuerySource;
  }

  public ActiveRecordContext setNamedQuerySource(INamedQuerySource namedQuerySource) {
    this.namedQuerySource = namedQuerySource;
    return this;
  }
  
  public PlatformTransactionManager getPlatformTransactionManager() {
    return platformTransactionManager;
  }

  public ActiveRecordContext setPlatformTransactionManager(PlatformTransactionManager platformTransactionManager) {
    this.platformTransactionManager = platformTransactionManager;
    return this;
  }
  
  /**
   * Sets the values in the current context to those in the given context
   * @return the current context, allowing fluent behavior
   */
  public ActiveRecordContext setValuesFrom(ActiveRecordContext other) {
    if(other.getDataSource() != null) {
      setDataSource(other.getDataSource());
    }
    
    if(other.getNamedQuerySource() != null) {
      setNamedQuerySource(other.getNamedQuerySource());
    }
    
    if(other.getPlatformTransactionManager() != null) {
      setPlatformTransactionManager(other.getPlatformTransactionManager());
    }
    
    return this;
  }

  @Override
  public String toString() {
    return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
  }
}
